/*
 ------------------------------------------------------------------------------
 Copyright (C) 2009-2011 Eternal Games.

 This file is part of the Eternal Tech source code.

 The Eternal Tech source code is free software; you can redistribute it and/or
 modify it under the terms of the GNU General Public License as published by
 the Free Software Foundation; either version 2 of the License, or (at your
 option) any later version.

 The Eternal Tech source code is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
 or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
 more details.

 You should have received a copy of the GNU General Public License along with
 the Eternal Tech source code; if not, write to the Free Software Foundation, Inc.,
 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 ------------------------------------------------------------------------------
*/


//
// editor.cpp - Integrated editors interface
//


#include "../qcommon/qcommon.h"
#include "../client/cl_local.h"


struct editor_t {
	bool					active;
	char					name[32];

	editorCallbacks_t		callbacks;
};

static editor_t				ed;


/*
 ==============================================================================

    LAUNCH AND CLOSE

 ==============================================================================
*/


/*
 ==================
 ED_LaunchEditor

 TODO: Check for running a local server and pure server?
 ==================
*/
bool ED_LaunchEditor (const char *name, editorCallbacks_t *callbacks)
{
	void	*wndHandle;

	if (ed.active)
	{
		if (!Str_ICompare(ed.name, name))
		{
			Com_Printf("The %s editor is already active\n", ed.name);
			return false;
		}

		Com_Printf("You must close the %s editor to launch the %s editor\n", ed.name, name);
		return false;
	}

	if (cls.state != CS_ACTIVE)
	{
		Com_Printf("You must be in a level to launch the %s editor\n", name);
		return false;
	}

	if (!CVar_AllowCheats())
	{
		Com_Printf("You must enable cheats to launch the %s editor\n", name);
		return false;
	}

	if (Win_IsWindowFullscreen())
	{
		Com_Printf("You must be running the game in windowed mode to launch the %s editor\n", name);
		return false;
	}

	Com_Printf("Launching %s editor...\n", name);

	// Set the editor state
	ed.active = true;
	Str_Copy(ed.name, name, sizeof(ed.name));

	ed.callbacks = *callbacks;

	// Create the editor window
	wndHandle = ed.callbacks.createWindow();
	if (!wndHandle)
	{
		ED_CloseEditor();
		return false;
	}

	Win_SetEditorWindow(wndHandle);

	return true;
}

/*
 ==================
 ED_CloseEditor
 ==================
*/
void ED_CloseEditor ()
{
	if (!ed.active)
		return;

	Com_Printf("Closing %s editor...\n", ed.name);

	// Destroy the editor window
	Win_SetEditorWindow(NULL);

	ed.callbacks.destroyWindow();

	// Clear the editor state
	memset(&ed, 0, sizeof(editor_t));
}


/*
 ==============================================================================

    EVENTS

 ==============================================================================
*/


/*
 ==================
 ED_IsEditorActive
 ==================
*/
bool ED_IsEditorActive ()
{
	return ed.active;
}

/*
 ==================
 ED_EnumMaterialDefs
 ==================
*/
void ED_EnumMaterialDefs (void (*callback)(const char *name))
{
	if (!ed.active)
		return;

	R_EnumMaterialScripts(callback);
}

/*
 ==================
 ED_MouseEvent
 ==================
*/
bool ED_MouseEvent ()
{
	if (!ed.active)
		return false;

	// Perform a callback if possible
	if (!ed.callbacks.mouseEvent)
		return false;

	return ed.callbacks.mouseEvent();
}


/*
 ==============================================================================

    DRAWING

 ==============================================================================
*/


/*
 ==================
 ED_Draw
 ==================
*/
void ED_Draw ()
{
	if (!ed.active)
		return;

	// Perform a callback if possible
	if (!ed.callbacks.draw)
		return;

	ed.callbacks.draw();
}

/*
 ==================
 ED_DrawBox
 ==================
*/
void ED_DrawBox (const vec3_t corners[8], const vec3_t color)
{
	if (!ed.active)
		return;

	R_DebugDrawBox(corners, color);
}